UNPKG

medusa-plugin-reviews-and-ratings

Version:

Medusa plugin to add product reviews and ratings functionality in the project.

147 lines (146 loc) 6.12 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DELETE = exports.PUT = exports.POST = exports.GET = void 0; const medusa_1 = require("@medusajs/medusa"); const product_review_1 = require("../../../../models/product-review"); const utils_1 = require("@medusajs/utils"); const fs_1 = __importDefault(require("fs")); const image_1 = __importDefault(require("@medusajs/medusa/dist/repositories/image")); const utils_2 = require("@medusajs/utils"); const GET = async (req, res) => { const { id: product_id } = req.params; const { limit, page } = req.query; const parsedLimit = parseInt(limit, 10) || 0; const parsedPage = parseInt(page, 10) || 0; const offset = (parsedPage - 1) * parsedLimit < 0 ? 0 : (parsedPage - 1) * parsedLimit; const manager = req.scope.resolve("manager"); const productReviewRepo = manager.getRepository(product_review_1.ProductReview); const productRepo = manager.getRepository(medusa_1.Product); const product = await productRepo.findOneBy({ id: product_id, }); if (!product) { throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_FOUND, "Product not found"); } const [reviews, ratings] = await Promise.all([ productReviewRepo.find({ where: { product: { id: product_id } }, relations: ["customer", "images"], skip: offset, take: parsedLimit, order: { created_at: "DESC", }, }), productReviewRepo.find({ select: ["rating"], where: { product: { id: product_id } }, }), ]); const star_wise_data = { star_1: { total: 0, bar_percentage: 0 }, star_2: { total: 0, bar_percentage: 0 }, star_3: { total: 0, bar_percentage: 0 }, star_4: { total: 0, bar_percentage: 0 }, star_5: { total: 0, bar_percentage: 0 }, }; ratings.forEach((rating) => { if (rating.rating > 0) star_wise_data[`star_${rating.rating}`].total++; }); const total_ratings = ratings.length; Object.entries(star_wise_data).forEach(([key, value]) => (star_wise_data[key].bar_percentage = (value.total / total_ratings) * 100 || 0)); const average_rating = ratings.reduce((total, rating) => total + rating.rating, 0) / total_ratings || 0; const total_pages = Math.ceil(total_ratings / parsedLimit) ? Math.ceil(total_ratings / parsedLimit) : 1; return res.json({ reviews, total_ratings, total_pages, average_rating, star_wise_data, }); }; exports.GET = GET; const POST = async (req, res) => { const { id: product_id } = req.params; const { customer_id } = req.user; const { title, description, rating } = req.body; const manager = req.scope.resolve("manager"); const fileService = req.scope.resolve("fileService"); const productRepo = manager.getRepository(medusa_1.Product); const customerRepo = manager.getRepository(medusa_1.Customer); const imageRepo = manager.withRepository(image_1.default); const productReviewRepo = manager.getRepository(product_review_1.ProductReview); const isProduct = await productRepo.findOneBy({ id: product_id, }); if (!isProduct) { throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_FOUND, "Product not found"); } const isReview = await productReviewRepo.findOneBy({ product: { id: product_id }, customer: { id: customer_id }, }); if (isReview) { throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_ALLOWED, "You can write review only once"); } const imageUrls = await (0, utils_1.promiseAll)(req.files.map(async (f) => { return fileService.upload(f).then((result) => { fs_1.default.unlinkSync(f.path); return result.url; }); })); const customer = await customerRepo.findOneBy({ id: customer_id }); const product = await productRepo.findOneBy({ id: product_id }); const images = await imageRepo.upsertImages(imageUrls); const newReview = new product_review_1.ProductReview(); newReview.customer = customer; newReview.product = product; newReview.images = images; newReview.title = title; newReview.description = description; newReview.rating = rating; const review = await productReviewRepo.save(newReview); return res.json(review); }; exports.POST = POST; const PUT = async (req, res) => { const { id: product_review_id } = req.params; const { title, description, rating } = req.body; const manager = req.scope.resolve("manager"); const productReviewRepo = manager.getRepository(product_review_1.ProductReview); const updatedReview = await productReviewRepo.findOneBy({ id: product_review_id, }); if (!updatedReview) { throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_FOUND, "Review not found"); } updatedReview.title = title; updatedReview.description = description; updatedReview.rating = rating; const review = await productReviewRepo.save(updatedReview); return res.json(review); }; exports.PUT = PUT; const DELETE = async (req, res) => { const { id: product_review_id } = req.params; const manager = req.scope.resolve("manager"); const productReviewRepo = manager.getRepository(product_review_1.ProductReview); const review = await productReviewRepo.findOne({ where: { id: product_review_id }, relations: ["images"], }); if (!review) { throw new utils_2.MedusaError(utils_2.MedusaError.Types.NOT_FOUND, "Review not found"); } await productReviewRepo.remove(review); return res.send("Review deleted"); }; exports.DELETE = DELETE;